package exercice_2;

import java.awt.Graphics;
import java.awt.Point;

public class HkSol extends Hk {

    /**
     * Constructeur normal
     * 
     * @param profondeur correspond au nombre d'itérations
     */
    public HkSol(int prof) {
        super(prof);
    }


    /** 
     * 
     * @param x Abscisse du centre du carré 
     * @param y Ordonnée du centre du carré 
     * @param taille longueur coté du carré
     * @param n profondeur de récursion
     * @param drawingArea Objet Graphics pour déssiner
     */
    public void drawHk(int x,int y, int taille, int n, Graphics drawingArea) {
        drawHilbertH(x,y,taille, n, drawingArea);
    }



    /** Trace la courbe d'Hilbert sur le HAUT ("⊓")
     * @param x Abscisse du centre du carré 
     * @param y Ordonnée du centre du carré 
     * @param taille longueur coté du carré
     * @param n profondeur de récursion
     * @param drawingArea Objet Graphics pour déssiner
     */
    public Point[] drawHilbertH(int x,int y, int taille, int n, Graphics g) {
        if (n==1){
            // Définir les coordonnées des points du carré
            //            
            Point pt1 = new Point(x - (taille/2), y + (taille/2));
            Point pt2 = new Point(pt1.x, y - (taille/2));
            Point pt3 = new Point(x + (taille/2), pt2.y);
            Point pt4 = new Point(pt3.x, pt1.y);

            //Relier les points pour former la courbe de Hilbert haut
            //
            g.drawLine(pt1.x,pt1.y, pt2.x, pt2.y);
            g.drawLine(pt2.x,pt2.y,pt3.x, pt3.y);
            g.drawLine(pt3.x,pt3.y,pt4.x,pt4.y);

            //Retourner la ligne du carré qui n'a pas été tracée
            //
            Point[] ptResultat = {pt1, pt4};  
            return ptResultat;
        }
        else{
            Point[] ptTmp;
            Point[] ptTmp2;
            Point[] ptResultat=new Point[2];

            //Tracer la courbe de hilbert de droite
            //
            ptTmp = drawHilbertD(x-(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la courbe de hilbert du haut
            //
            ptTmp2 = drawHilbertH(x-(taille/2),y-(taille/2),taille/2, n-1,g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[1].x,ptTmp[1].y,ptTmp2[0].x,ptTmp2[0].y);

            ptResultat[0]=ptTmp[0];

            //Tracer la courbe de hilbert du haut
            //
            ptTmp = drawHilbertH(x+(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp2[1].x,ptTmp2[1].y,ptTmp[0].x,ptTmp[0].y);

            //Tracer la courbe de hilbert de gauche
            //
            ptTmp2=drawHilbertG(x+(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[1].x,ptTmp[1].y,ptTmp2[0].x,ptTmp2[0].y);

            ptResultat[1]=ptTmp2[1];
            return ptResultat;
        }
    }


    /** 
     * Trace la courbe d'Hilbert sur la DROITE ("]")
     * @param x Abscisse du centre du carré 
     * @param y Ordonnée du centre du carré 
     * @param taille longueur coté du carré
     * @param n profondeur de récursion
     * @param drawingArea Objet Graphics pour déssiner
     */  
    public Point[] drawHilbertD(int x, int y, int taille, int n, Graphics g) {
        if (n==1){
            // Définir les coordonnées des points du carré
            //            
            Point pt1 = new Point(x - (taille/2), y + (taille/2));
            Point pt2 = new Point(pt1.x, y - (taille/2));
            Point pt3 = new Point(x + (taille/2), pt2.y);
            Point pt4 = new Point(pt3.x, pt1.y);

            //Relier les points pour former la courbe de Hilbert à droite
            //
            g.drawLine(pt1.x, pt1.y, pt4.x,pt4.y);
            g.drawLine(pt4.x, pt4.y, pt3.x, pt3.y);
            g.drawLine(pt3.x, pt3.y, pt2.x, pt2.y);

            //Retourner la ligne du carré qui n'a pas été tracée
            //
            Point[] ptResultat = {pt1, pt2};
            return ptResultat;
        }
        else{
            Point[] ptTemp;
            Point[] ptTemp2;
            Point[] ptResultat = new Point[2];

            //Tracer la courbe de hilbert du haut
            //
            ptTemp = drawHilbertH(x-(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la courbe de hilbert de droite
            //
            ptTemp2 = drawHilbertD(x+(taille/2),y+(taille/2),taille/2, n-1, g);

            //Ajouter les points retournés précédement dans le resultat
            //
            ptResultat[0]=ptTemp[0];

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTemp[1].x,ptTemp[1].y,ptTemp2[0].x,ptTemp2[0].y);

            //Tracer la courbe de hilbert de droite
            //
            ptTemp = drawHilbertD(x+(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTemp2[1].x,ptTemp2[1].y,ptTemp[0].x,ptTemp[0].y);

            //Tracer la courbe de hilbert du bas
            //
            ptTemp2=drawHilbertB(x-(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTemp[1].x,ptTemp[1].y,ptTemp2[1].x,ptTemp2[1].y);

            //Ajouter les points retournés précédement dans le resultat
            //
            ptResultat[1]=ptTemp2[0];


            return ptResultat;
        }
    }



    /** Trace la courbe d'Hilbert sur la GAUCHE ("[")
     * @param x Abscisse du centre du carré 
     * @param y Ordonnée du centre du carré 
     * @param taille longueur coté du carré
     * @param n profondeur de récursion
     * @param drawingArea Objet Graphics pour déssiner
     */
    public Point[] drawHilbertG(int x, int y, int taille, int n, Graphics g) {
        if (n==1){   
            // Définir les coordonnées des points du carré
            //
            Point pt1 = new Point(x - (taille/2), y + (taille/2));
            Point pt2 = new Point(pt1.x, y - (taille/2));
            Point pt3 = new Point(x + (taille/2), pt2.y);
            Point pt4 = new Point(pt3.x, pt1.y);

            //Relier les points pour former la courbe de Hilbert vers la gauche
            //
            g.drawLine(pt3.x,pt3.y,pt2.x,pt2.y);
            g.drawLine(pt2.x,pt2.y,pt1.x,pt1.y);
            g.drawLine(pt1.x,pt1.y,pt4.x,pt4.y);

            //Retourner la ligne du carré qui n'a pas été tracée
            //
            Point[] ptResultat = {pt3, pt4};
            return ptResultat;
        }
        else{
            Point[] ptTmp;
            Point[] ptTmp2;
            Point[] ptResultat=new Point[2];

            //Tracer la courbe de hilbert du haut
            //
            ptTmp = drawHilbertH(x+(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la courbe de hilbert de gauche
            //
            ptTmp2 = drawHilbertG(x-(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[0].x,ptTmp[0].y,ptTmp2[1].x,ptTmp2[1].y);

            ptResultat[1]=ptTmp[1];

            //Tracer la courbe de hilbert de gauche
            //
            ptTmp = drawHilbertG(x-(taille/2),y-(taille/2),taille/2, n-1,g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp2[0].x,ptTmp2[0].y,ptTmp[1].x,ptTmp[1].y);

            //Tracer la courbe de hilbert du bas
            //
            ptTmp2 = drawHilbertB(x+(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[0].x,ptTmp[0].y,ptTmp2[0].x,ptTmp2[0].y);

            ptResultat[0]=ptTmp2[1];
            return ptResultat;
        }
    }


    /** Trace la courbe d'Hilbert sur le BAS ("U")
     * @param x Abscisse du centre du carré 
     * @param y Ordonnée du centre du carré 
     * @param taille longueur coté du carré
     * @param n profondeur de récursion
     * @param drawingArea Objet Graphics pour déssiner
     */
    public Point[] drawHilbertB(int x,int y,int taille, int n, Graphics g) {
        if (n==1){

            // Définir les coordonnées des points du carré
            // 
            Point pt1 = new Point(x - (taille/2), y + (taille/2));
            Point pt2 = new Point(pt1.x, y - (taille/2));
            Point pt3 = new Point(x + (taille/2), pt2.y);
            Point pt4 = new Point(pt3.x, pt1.y);

            //Relier les points pour former la courbe de Hilbert vers le bas
            //
            g.drawLine(pt2.x,pt2.y,pt1.x,pt1.y);
            g.drawLine(pt1.x,pt1.y,pt4.x,pt4.y);
            g.drawLine(pt4.x,pt4.y,pt3.x,pt3.y);

            //Retourner la ligne du carré qui n'a pas été tracée
            //
            Point[] ptResultat = {pt2,pt3};
            return ptResultat;
        }
        else{
            Point[] ptTmp;
            Point[] ptTmp2;
            Point[] ptResultat=new Point[2];

            //Tracer la courbe de hilbert de droite
            //
            ptTmp = drawHilbertD(x-(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la courbe de hilbert du bas
            //
            ptTmp2 = drawHilbertB(x-(taille/2),y+(taille/2),taille/2, n-1, g);

            ptResultat[0]=ptTmp[1];

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[0].x,ptTmp[0].y,ptTmp2[0].x,ptTmp2[0].y);

            //Tracer la courbe de hilbert du bas
            //
            ptTmp = drawHilbertB(x+(taille/2),y+(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp2[1].x,ptTmp2[1].y,ptTmp[0].x,ptTmp[0].y);

            //Tracer la courbe de hilbert de gauche
            //
            ptTmp2 = drawHilbertG(x+(taille/2),y-(taille/2),taille/2, n-1, g);

            //Tracer la ligne reliant les 2 courbes hilbert précédement tracées
            //
            g.drawLine(ptTmp[1].x,ptTmp[1].y,ptTmp2[1].x,ptTmp2[1].y);

            ptResultat[1]=ptTmp2[0];
            return ptResultat;
        }
    }
}
